import {ElButton, ElUpload, ElMessage} from 'element-plus'
import type {UploadProps, UploadFile, UploadFiles} from 'element-plus'
import {getToken} from '@/utils/auth'

type Props = {
    url: string,
    limit?: string | number | undefined,
    fileSize?: number | undefined,
    multiple?: boolean | undefined,
    uploadFileButtonName?: string,
    fileType: string[],
    params?: Record<string, any>,
    disabled?: boolean | undefined,
    autoUpload?: boolean,
    showFileList?: boolean,
}

const useUploadFile: import('vue').DefineComponent = defineComponent({
    components: {ElButton, ElUpload},
    setup(_: Record<string, any>, {attrs, emit}) {
        const {
            url = '',
            limit = 1,
            fileSize = 15,
            multiple = false,
            uploadFileButtonName = '上传',
            fileType = ["doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "pdf"],
            params = {},
            disabled = false,
            autoUpload = true,
            showFileList = false
        } = unref(attrs as Props)
        const uploadFileUrl = ref<string>(`${import.meta.env.VITE_APP_BASE_URL}${url}`)
        const headers = reactive<Record<string, string>>({
            token: getToken()
        })
        let fileList = ref<any[]>([])
        let loading = ref<boolean>(false)

        // 上传前校检格式和大小
        const handleBeforeUpload: UploadProps['beforeUpload'] = (file: any): boolean => {
            loading.value = true
            // 校检文件类型
            if (fileType.length) {
                const fileName = file.name.split('.');
                const fileExt = fileName[fileName.length - 1];
                const isTypeOk = fileType.indexOf(fileExt) >= 0;
                if (!isTypeOk) {
                    ElMessage.warning({
                        message: `文件格式不正确, 请上传${fileType.join("/")}格式文件!`
                    })
                    loading.value = false
                    return false;
                }
            }
            // 校检文件大小
            if (fileSize) {
                const isLt = file.size / 1024 / 1024 < fileSize;
                if (!isLt) {
                    ElMessage.error({
                        message: `上传文件大小不能超过 ${fileSize} MB!`
                    })
                    loading.value = false
                    return false;
                }
            }
            return true;
        }
        // 文件个数超出
        const handleExceed: UploadProps['onExceed'] = (): void => {
            loading.value = false
            ElMessage.error({
                message: `上传文件数量不能超过 ${limit} 个!`
            })
        }
        // 上传失败
        const handleUploadError: UploadProps['onError'] = (error: any): void => {
            loading.value = false
            ElMessage.error({
                message: `上传文件失败：${JSON.parse(error.message).message}`,
                duration: 4000
            })
        }
        // 上传成功回调
        const handleUploadSuccess: UploadProps['onSuccess'] = (res, file): void => {
            if (res.code === 200) {
                fileList.value = []
                loading.value = false
                ElMessage.success({
                    message: '文件上传成功'
                })
                emit('uploadSuccessRes', res.data)
            } else {
                fileList.value = []
                loading.value = false
                ElMessage.error({
                    message: res.message
                })
            }
        }
        const handleChange: UploadProps['onChange'] = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
            if (!autoUpload) {
                const Files = uploadFiles.map(item => item.raw)
                if (multiple) {
                    emit('update:file', Files)
                } else {
                    emit('update:file', Files[0])
                }
            }
        }
        const handleRemove: UploadProps['onRemove'] = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
            if (!autoUpload) {
                const Files = uploadFiles.map(item => item.raw)
                if (multiple) {
                    emit('update:file', Files)
                } else {
                    emit('update:file', Files)
                }
            }
        }
        return (): JSX.Element => (
            <ElUpload
                v-model:file-list={fileList.value}
                multiple={multiple}
                action={uploadFileUrl.value}
                before-upload={handleBeforeUpload}
                limit={limit as number}
                on-error={handleUploadError}
                on-exceed={handleExceed}
                on-success={handleUploadSuccess}
                on-remove={handleRemove}
                on-change={handleChange}
                show-file-list={showFileList}
                headers={headers}
                data={params}
                auto-upload={autoUpload}
            >
                <ElButton type="primary" disabled={disabled} loading={loading.value}>
                    {uploadFileButtonName}
                </ElButton>
            </ElUpload>
        )
    }
})
export default useUploadFile
